import request from "@/utils/request";
import { decimals2Amount, amount2Decimals } from "@/utils/number";
import { AGGREGATOR } from "@/config/config";
import { getChainIdByCode } from "@/config/chain";
import store from "@/store";
const TSE = "0x4f878f1d43c8bc18984f278db7ca43e749c78801-bsc";

const OOQuote = async (chainCode, params) => {
  try {
    const { data } = await request({
      url: `https://open-api.openocean.finance/v3/${chainCode}/quote`,
      params: {
        inTokenAddress: "0x9029FdFAe9A03135846381c7cE16595C3554e10A",
        outTokenAddress: "0xe9e7cea3dedca5984780bafc599bd69add087d56",
        amount: "10",
        gasPrice: "5",
        slippage: "300",
        ...params,
      },
    });
    const { estimatedGas, inToken, inAmount, outToken, outAmount } = data;
    return {
      aggregator: AGGREGATOR.OpenOcean,
      inAmount,
      inToken,
      outAmount,
      outAmountNum: +decimals2Amount(outAmount, 18),
      outToken,
      estimatedGas,
    };
  } catch (e) {
    return {
      outAmountNum: 0,
    };
  }
};

const OneInchQuote = async (chainCode, params) => {
  try {
    const chainId = getChainIdByCode(chainCode);
    const data = await request({
      url: `https://api.1inch.io/v4.0/${chainId}/quote`,
      params: {
        fromTokenAddress: params.inTokenAddress,
        toTokenAddress: params.outTokenAddress,
        amount: amount2Decimals(params.amount, 18),
      },
    });
    const { estimatedGas, fromToken, fromTokenAmount, toToken, toTokenAmount } = data;
    return {
      aggregator: AGGREGATOR.OneInch,
      inAmount: fromTokenAmount,
      inToken: fromToken,
      outAmount: toTokenAmount,
      outAmountNum: +decimals2Amount(toTokenAmount, 18),
      outToken: toToken,
      estimatedGas,
    };
  } catch (e) {
    return {
      outAmountNum: 0,
    };
  }
};

export const quote = async (chainCode, params) => {
  const ooQuoteRes = await OOQuote(chainCode, params);
  const oneInchQuoteRes = await OneInchQuote(chainCode, params);
  const quoteList = [ooQuoteRes, oneInchQuoteRes];
  return quoteList.sort((a, b) => {
    return a.outAmountNum > b.outAmountNum ? -1 : 1;
  })[0];
};

export const OOSwapQuote = async (chainCode, params) => {
  try {
    const { data } = await request({
      url: `https://open-api.openocean.finance/v3/${chainCode}/swap_quote`,
      params: {
        inTokenAddress: "0x9029FdFAe9A03135846381c7cE16595C3554e10A",
        outTokenAddress: "0xe9e7cea3dedca5984780bafc599bd69add087d56",
        amount: "10",
        gasPrice: "5",
        slippage: "3",
        referrer: "0x0000000000000000000000000000000000000000",
        ...params,
      },
    });
    const { inToken, outToken, inAmount, outAmount, minOutAmount } = data;
    return {
      aggregator: AGGREGATOR.OpenOcean,
      inTokenSymbol: inToken.symbol,
      inTokenAddress: inToken.address,
      inAmountNum: +decimals2Amount(inAmount, inToken.decimals),
      inAmount: inAmount,
      outTokenSymbol: outToken.symbol,
      outTokenAddress: outToken.address,
      outAmountNum: +decimals2Amount(outAmount, outToken.decimals),
      minOutAmount: +decimals2Amount(minOutAmount, outToken.decimals),
      data: data.data,
    };
  } catch (e) {
    return {
      outAmountNum: 0,
    };
  }
};

export const oneInchSwapQuote = async (chainCode, params) => {
  try {
    const chainId = getChainIdByCode(chainCode);
    const data = await request({
      url: `https://api.1inch.io/v4.0/${chainId}/swap`,
      params: {
        fromTokenAddress: params.inTokenAddress,
        toTokenAddress: params.outTokenAddress,
        amount: amount2Decimals(params.amount, 18),
        fromAddress: params.account,
        slippage: "5",
        disableEstimate: "true",
      },
    });
    const { fromToken, toToken, tx, fromTokenAmount, toTokenAmount } = data;
    return {
      aggregator: AGGREGATOR.OneInch,
      inTokenSymbol: fromToken.symbol,
      inTokenAddress: fromToken.address,
      inAmountNum: +decimals2Amount(fromTokenAmount, fromToken.decimals),
      inAmount: fromTokenAmount,
      outTokenSymbol: toToken.symbol,
      outTokenAddress: toToken.address,
      outAmountNum: +decimals2Amount(toTokenAmount, toToken.decimals),
      data: tx.data,
    };
  } catch (e) {
    return {
      outAmountNum: 0,
    };
  }
};

export const swapQuote = async (chainCode, params) => {
  const ooSwapQuoteRes = await OOSwapQuote(chainCode, params);
  const oneSwapInchQuoteRes = await oneInchSwapQuote(chainCode, params);
  const quoteList = [ooSwapQuoteRes, oneSwapInchQuoteRes];
  return quoteList.sort((a, b) => {
    return a.outAmountNum > b.outAmountNum ? -1 : 1;
  })[0];
};

export const getTSEPrice = async () => {
  try {
    const { data } = await request({
      method: "POST",
      url: `https://api.dex.guru/v2/tokens/`,
      data: { ids: [TSE] },
    });
    const price = data[0].priceUSD;
    console.log("getTSEPrice", price);
    return price;
  } catch (e) {
    return 0;
  }
};

export const getGasPrice = async () => {
  try {
    const { state } = store;
    const { provider } = state;
    const price = await provider.eth.getGasPrice();
    return decimals2Amount(price, 9);
  } catch(e) {
    return 0;
  }
};

export const getTokenPrice = async (tokens) => {
  try {
    const { data } = await request({
      method: "POST",
      url: "https://open-api.openocean.finance/v3/bsc/specify_tokenList",
      data: { tokens },
    });
    const temp = {};
    for (var i=0;i<data.length;i++) {
      const { symbol, usd } = data[i];
      temp[symbol] = usd;
    }
    return temp;
  } catch(e) {
    return 0;
  }
};
export const getTokenPriceSingle = async (token) => {
  try {
    const data = await getTokenPrice([token]);
    return data && data[token];
  } catch(e) {
    return 0;
  }
};

export const addNFT = async (tx_hash, metadata, price) => {
  const { data } = await request({
    method: "POST",
    url: "https://market-api.tokenswap.exchange/nft",
    data: { tx_hash, metadata, price },
  });
  return data;
};

export const getNFTList = async (account) => {
  if (!account) return [];

  const { data } = await request({
    url: `https://market-api.tokenswap.exchange/nft/owner?account=${account}`,
  });
  return data;
};

export const getNFTAll = async () => {
  const { data } = await request({
    url: `https://market-api.tokenswap.exchange/nft/all`,
  });
  return data;
};


export const submitTransactions = async (data) => {
  const res = await request({
    method: "POST",
    url: `https://market-api.tokenswap.exchange/transactions`,
    data,
  });
  return res;
}
